package com.sunrise.xdoc.service.impl;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hibernate.FetchMode;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Service;

import com.sunrise.xdoc.dao.IDinhMucDao;
import com.sunrise.xdoc.entity.catalog.SanPham;
import com.sunrise.xdoc.entity.config.Ban;
import com.sunrise.xdoc.entity.order.ChiTietDonHang;
import com.sunrise.xdoc.entity.order.DinhMuc;
import com.sunrise.xdoc.entity.order.DonHang;
import com.sunrise.xdoc.entity.order.DonHang.TrangThaiDonHang;
import com.sunrise.xdoc.service.AbstractService;
import com.sunrise.xdoc.service.IOrderService;

@Service("orderService")
public class OrderService extends AbstractService implements IOrderService {
	private static final long serialVersionUID = 2817704552452964162L;

	@Override
	public List<DonHang> getDonHangChuaThanhToans() {
		DetachedCriteria dc = getDaoHelper().getDao(DonHang.class).getDetachedCriteria();
		dc.setFetchMode("bans", FetchMode.JOIN);
		dc.add(Restrictions.not(Restrictions.eq("trangThai", TrangThaiDonHang.DA_THANH_TOAN)));
		return getDaoHelper().getDao(DonHang.class).findByCriteria(dc);
	}

	@Override
	public long getGeneratedCode() {
		return getDaoHelper().getDao(DonHang.class).getNextSequence("MA_CODE_DON_HANG");
	}

	@Override
	public DonHang saveOrUpdateDonHang(DonHang donHang) {
		getDaoHelper().getDao(DonHang.class).saveOrUpdate(donHang);
		return donHang;
	}

	@Override
	public void canBangDinhMucAll() {
		getDaoHelper().getDao(DinhMuc.class, IDinhMucDao.class).canBangDinhMucAll();
	}

	@Override
	public void saveOrUpdateDinhMuc(DinhMuc dm) {
		getDaoHelper().getDao(DinhMuc.class).saveOrUpdate(dm);
	}

	@Override
	public ChiTietDonHang saveOrUpdateChiTietDH(ChiTietDonHang ctDH) {
		getDaoHelper().getDao(ChiTietDonHang.class).saveOrUpdate(ctDH);
		return ctDH;
	}

	@Override
	public void deleteDonHangs(Collection<DonHang> donHangs) {
		getDaoHelper().getDao(DonHang.class).deleteAll(donHangs);
	}

	@Override
	public DonHang gopDonHangs(Collection<DonHang> donHangs, Set<Ban> bans) {
		DonHang newDH = new DonHang();
		List<ChiTietDonHang> ctDHs = new ArrayList<>();
		for (DonHang dh : donHangs) {
			ctDHs.addAll(dh.getChiTietDonHangs());
		}
		ctDHs = new ArrayList<>(gopChiTietDHs(ctDHs, newDH));
		newDH.setChiTietDonHangs(ctDHs);
		newDH.setCode(String.valueOf(getGeneratedCode()));
		newDH.getBans().addAll(bans);
		// TODO newDH.setGiamGia(giamGia)
		// TODO newDH.setMaNhanVienPhucVu(maNhanVienPhucVu)
		updateDonHangTheoChiTietDonHangs(newDH);
		getDaoHelper().getDao(DonHang.class).deleteAll(donHangs);
		getDaoHelper().getDao(DonHang.class).saveOrUpdate(newDH);
		return newDH;
	}

	private void updateDonHangTheoChiTietDonHangs(DonHang dh) {
		long tongGiaSP = 0L;
		for (ChiTietDonHang ctdh : dh.getChiTietDonHangs()) {
			tongGiaSP += ctdh.getSoLuong() * ctdh.getDonGia();
		}
		dh.setTongGiaSanPham(tongGiaSP);
	}

	private Collection<ChiTietDonHang> gopChiTietDHs(List<ChiTietDonHang> ctDHs, DonHang newDH) {
		Map<SanPham, ChiTietDonHang> sp2Ctdh = new HashMap<>();
		for (ChiTietDonHang ct : ctDHs) {
			ChiTietDonHang ctdh = sp2Ctdh.get(ct.getSanPham());
			if (ctdh == null || !ctdh.getSanPham().equals(ct.getSanPham())) {
				ChiTietDonHang newCtdh = new ChiTietDonHang();
				newCtdh.setDonGia(ct.getDonGia());
				newCtdh.setDonHang(newDH);
				newCtdh.setSanPham(ct.getSanPham());
				newCtdh.setSoLuong(ct.getSoLuong());
				sp2Ctdh.put(ct.getSanPham(), newCtdh);
			} else {
				ctdh.setSoLuong(ctdh.getSoLuong() + ct.getSoLuong());
				ctdh.setDonHang(newDH);
			}
		}
		return sp2Ctdh.values();
	}
}
